import 'dart:async';

import 'package:flutter/material.dart';
import 'package:kq_flutter_core_widget/utils/kq_screen_util.dart';
import 'package:get/get.dart';
import 'package:kq_flutter_tv_widgets/config/kq_global.dart';
import 'package:kq_flutter_tv_widgets/resources/images.dart';

import '../../resources/kq_theme_colors.dart';
import '../../theme/kq_theme_manager.dart';
import 'pull_down_menu_controller.dart';

// typedef OnItemTap<T> = void Function(T value);
typedef OverlayBack = Widget Function();

// ignore: must_be_immutable
class PullDownHeader extends StatefulWidget {
  final GlobalKey stackKey;

  /// 控制器
  PullDownMenuController controller;

  ///标题绘制器，返回标题要显示的文本内容
  final String Function(dynamic item, int menuIndex) titleRender;

  ///指定位置是否外部自己控制header数据的刷新,自定义widget必须外部控制数据更新，如果true或者未实现回调，则需外部自己刷新，如果false则内容做更新
  bool Function(int index)? isSelfControlHeaderData;

  /// 指定位置自定义,如果需要自定义返回widget，否则返回null
  Widget? Function(int index, PullDownMenuController menuController)?
      renderCustomHeaderView;

  /// 当前菜单回调，展开还是收起
  void Function(int index, bool isShow, PullDownMenuController menuController)?
      getCurrentStatus;

  /// 指定头部header每个item的宽度
  double Function(int index)? headerViewWidth;

  ///初始化数据
  List<dynamic> initChosenData;

  ///header高度，默认64
  final double? height;

  /// 边框线的颜色
  final Color borderColor;

  /// 边框的宽度
  final double? borderWidth;

  ///背景色
  final Color? bgColor;

  ///样式
  final TextStyle? style;

  ///下拉展开后的样式
  final TextStyle? dropDownStyle;

  ///icon下拉颜色
  final Color? iconDropDownColor;

  ///icon大小
  final double iconSize;

  ///icon默认颜色
  final Color iconColor;

  ///是否使用overlay
  final bool isUseOverlay;

  ///是否禁止下拉
  final bool Function(int menuIndex)? disabledRender;

  OverlayBack? menuListOverlay;

  PullDownHeader({
    Key? key,
    required this.stackKey,
    required this.controller,
    required this.titleRender,
    required this.initChosenData,
    this.isSelfControlHeaderData,
    this.renderCustomHeaderView,
    this.disabledRender,
    this.getCurrentStatus,
    this.headerViewWidth,
    this.height,
    this.borderColor = KqThemeColors.lineColor,
    this.borderWidth,
    this.bgColor,
    this.style,
    this.dropDownStyle,
    this.iconDropDownColor,
    this.iconSize = 20,
    this.iconColor = KqThemeColors.text26,
    this.isUseOverlay = false,
    this.menuListOverlay,
  }) : super(key: key);

  @override
  State<PullDownHeader> createState() => _PullDownHeaderState();
}

class _PullDownHeaderState extends State<PullDownHeader>
    with SingleTickerProviderStateMixin {
  bool _isShowDropDownItemWidget = false;
  final GlobalKey _keyDropDownHeader = GlobalKey();
  final TextStyle _dropDownStyle = TextStyle(
      color: KqThemeManager.getPullDownMenuConfig().selectColor ??
          KqThemeColors.bgBlue,
      fontSize: KqThemeManager.getPullDownMenuConfig().headFontSize);

  final TextStyle _normalStyle = TextStyle(
      color: KqThemeColors.text26,
      fontSize: KqThemeManager.getPullDownMenuConfig().headFontSize);

  Color? _iconDropDownColor;

  OverlayEntry? _overlayEntry;

  Timer? timer;

  @override
  void initState() {
    super.initState();
    initControllerChosenData();
    // Get.find<PullDownMenuController>().addListener(_onController);
    widget.controller.addListener(_onController);
    // _hideOverlay();
  }

  void initControllerChosenData() {
    Map<int, dynamic> chosenData = {};
    for (var i = 0; i < widget.initChosenData.length; i++) {
      var item = widget.controller.chosenData[i];
      if (widget.isSelfControlHeaderData != null) {
        bool isSelfControl = widget.isSelfControlHeaderData!(i);
        if (isSelfControl) {
          chosenData[i] = widget.initChosenData[i];
        } else {
          // var item = Get.find<PullDownMenuController>().chosenData[i];
          if (item != null) {
            chosenData[i] = item;
          } else {
            chosenData[i] = widget.initChosenData[i];
          }
        }
      } else {
        // var item = Get.find<PullDownMenuController>().chosenData[i];
        if (item != null) {
          chosenData[i] = item;
        } else {
          chosenData[i] = widget.initChosenData[i];
        }
      }
    }
    // Get.find<PullDownMenuController>().chosenData = chosenData;
    widget.controller.chosenData = chosenData;
  }

  _onController() {
    // if (Get.find<PullDownMenuController>().isRemoveMenu) {
    //   Get.find<PullDownMenuController>().isRemoveMenu = false;
    //   _hideOverlay();
    // }
    if (widget.controller.isRemoveMenu) {
      widget.controller.isRemoveMenu = false;
      _hideOverlay();
    }
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      key: _keyDropDownHeader,
      height: widget.height ?? 64.r,
      decoration: BoxDecoration(
        border: Border(
            bottom: BorderSide(
                width: widget.borderWidth ?? 1.r, color: widget.borderColor)),
      ),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: _renderHeaderView(),
      ),
    );
  }

  @override
  void deactivate() {
    // _hideOverlay();
    super.deactivate();
    _hideOverlay();
  }

  @override
  dispose() {
    // if (Get.isRegistered<PullDownMenuController>()) {
    //   Get.find<PullDownMenuController>().removeListener(_onController);
    // }
    widget.controller.removeListener(_onController);
    super.dispose();
  }

  void showCustomMenu(int index) {
    // int menuIndex = 0;
    // if (Get.isRegistered<PullDownMenuController>()) {
    //   menuIndex = Get.find<PullDownMenuController>().menuIndex;
    // }
    int menuIndex = widget.controller.menuIndex;
    if (widget.isUseOverlay) {
      final RenderBox dropDownItemRenderBox =
          _keyDropDownHeader.currentContext!.findRenderObject() as RenderBox;
      var position = dropDownItemRenderBox.localToGlobal(Offset.zero);
      var size = dropDownItemRenderBox.size;
      // if (Get.isRegistered<PullDownMenuController>()) {
      //   Get.find<PullDownMenuController>().dropDownMenuTop =
      //       size.height + position.dy;
      // }
      widget.controller.dropDownMenuTop = size.height + position.dy;
    } else {
      final RenderBox? overlay =
          widget.stackKey.currentContext!.findRenderObject() as RenderBox?;

      final RenderBox dropDownItemRenderBox =
          _keyDropDownHeader.currentContext!.findRenderObject() as RenderBox;
      var position =
          dropDownItemRenderBox.localToGlobal(Offset.zero, ancestor: overlay);
      var size = dropDownItemRenderBox.size;
      // if (Get.isRegistered<PullDownMenuController>()) {
      //   Get.find<PullDownMenuController>().dropDownMenuTop =
      //       size.height + position.dy;
      // }

      widget.controller.dropDownMenuTop = size.height + position.dy;
    }

    if (index == menuIndex && Get.isRegistered<PullDownMenuController>()) {
      if (widget.controller.isShow) {
        widget.getCurrentStatus?.call(index, false, widget.controller);
        widget.controller.hide();
        _hideOverlay();
      } else {
        widget.controller.show(index);
        _operateOverlay();
        if (widget.isUseOverlay) {
          timer?.cancel();
          timer = Timer(const Duration(milliseconds: 200), () {
            widget.controller.reload();
            widget.getCurrentStatus?.call(index, true, widget.controller);
          });
        } else {
          widget.getCurrentStatus?.call(index, true, widget.controller);
        }
      }
    } else if (Get.isRegistered<PullDownMenuController>()) {
      if (widget.controller.isShow) {
        widget.controller.hide(isShowHideAnimation: false);
        widget.controller.show(index);
        widget.getCurrentStatus?.call(index, true, widget.controller);
      } else {
        widget.controller.show(index);
        _operateOverlay();
        if (widget.isUseOverlay) {
          timer?.cancel();
          timer = Timer(const Duration(milliseconds: 200), () {
            widget.controller.reload();
            widget.getCurrentStatus?.call(index, true, widget.controller);
          });
        } else {
          widget.getCurrentStatus?.call(index, true, widget.controller);
        }
      }
    }
    setState(() {});
  }

  void _operateOverlay() {
    if (!widget.controller.isShow) {
      _hideOverlay();
    } else {
      _showOverlay();
    }
  }

  void _hideOverlay() {
    if (widget.isUseOverlay && _overlayEntry != null) {
      _overlayEntry!.remove();
      _overlayEntry = null;
    }
  }

  void _showOverlay() {
    if (widget.isUseOverlay) {
      _overlayEntry = _createOverlayEntry();
      Overlay.of(context).insert(_overlayEntry!);
    }
  }

  OverlayEntry _createOverlayEntry() {
    Widget menu = widget.menuListOverlay!();
    return OverlayEntry(
        builder: ((context) => Stack(
              children: [menu],
            )));
  }

  _renderHeaderView() {
    List<Widget> items = <Widget>[];
    initControllerChosenData();
    for (var i = 0; i < widget.initChosenData.length; i++) {
      var showItem = widget.initChosenData[i];
      if (widget.isSelfControlHeaderData != null) {
        bool isSelfControl = widget.isSelfControlHeaderData!(i);
        if (isSelfControl) {
          showItem = widget.initChosenData[i];
        } else {
          var item = widget.controller.chosenData[i];
          if (item != null) {
            showItem = item;
          } else {
            showItem = widget.initChosenData[i];
          }
        }
      } else {
        if (Get.isRegistered<PullDownMenuController>()) {
          var item = widget.controller.chosenData[i];
          if (item != null) {
            showItem = item;
          } else {
            showItem = widget.initChosenData[i];
          }
        } else {
          showItem = widget.initChosenData[i];
        }
      }
      if (widget.renderCustomHeaderView != null) {
        Widget? view = widget.renderCustomHeaderView!(i, widget.controller);
        if (view != null) {
          items.add(Expanded(
              child: SizedBox(
            height: widget.height ?? 64.r,
            child: view,
          )));
        } else {
          items.add(_menu(i, showItem));
        }
      } else {
        items.add(_menu(i, showItem));
      }
    }
    return items.toList();
  }

  _menu(int index, dynamic item) {
    int menuIndex = widget.controller.menuIndex;
    _isShowDropDownItemWidget = index == menuIndex && widget.controller.isShow;
    _iconDropDownColor = widget.iconDropDownColor ??
        KqThemeManager.getPullDownMenuConfig().selectColor;

    String title = widget.titleRender(item, index);

    bool disabled = false;
    if (widget.disabledRender != null) {
      disabled = widget.disabledRender!(index);
    }

    return Expanded(
        child: GestureDetector(
      onTap: () {
        if (disabled) {
          return;
        }
        //使用Overlay
        if (widget.isUseOverlay) {
          final RenderBox dropDownItemRenderBox =
              _keyDropDownHeader.currentContext!.findRenderObject()
                  as RenderBox;
          var position = dropDownItemRenderBox.localToGlobal(Offset.zero);
          var size = dropDownItemRenderBox.size;
          if (Get.isRegistered<PullDownMenuController>()) {
            widget.controller.dropDownMenuTop = size.height + position.dy;
            widget.controller.leftX = position.dx;
            widget.controller.rightX =
                KqScreenUtil().screenWidth - (position.dx + size.width);
            widget.controller.menuWidth = size.width;
          }
        } else {
          final RenderBox? overlay =
              widget.stackKey.currentContext!.findRenderObject() as RenderBox?;

          final RenderBox dropDownItemRenderBox =
              _keyDropDownHeader.currentContext!.findRenderObject()
                  as RenderBox;
          var position = dropDownItemRenderBox.localToGlobal(Offset.zero,
              ancestor: overlay);
          var size = dropDownItemRenderBox.size;
          widget.controller.dropDownMenuTop = size.height + position.dy;
          widget.controller.leftX = position.dx;
          widget.controller.rightX =
              KqScreenUtil().screenWidth - (position.dx + size.width);
          widget.controller.menuWidth = size.width;
        }

        if (index == menuIndex) {
          if (widget.controller.isShow) {
            widget.getCurrentStatus?.call(index, false, widget.controller);
            widget.controller.hide();
            _hideOverlay();
          } else {
            widget.controller.show(index);
            _operateOverlay();
            if (widget.isUseOverlay) {
              timer?.cancel();
              timer = Timer(const Duration(milliseconds: 200), () {
                widget.controller.reload();
                widget.getCurrentStatus?.call(index, true, widget.controller);
              });
            } else {
              widget.getCurrentStatus?.call(index, true, widget.controller);
            }
          }
        } else if (Get.isRegistered<PullDownMenuController>()) {
          if (widget.controller.isShow) {
            if (widget.controller.menuIndex != index) {
              widget.controller.isChangeIndex = true;
            }
            widget.controller.hide(isShowHideAnimation: false);
            widget.controller.show(index);
            widget.getCurrentStatus?.call(index, true, widget.controller);
          } else {
            widget.controller.show(index);
            _operateOverlay();
            if (widget.isUseOverlay) {
              timer?.cancel();
              timer = Timer(const Duration(milliseconds: 200), () {
                widget.getCurrentStatus?.call(index, true, widget.controller);
                widget.controller.reload();
              });
            } else {
              widget.getCurrentStatus?.call(index, true, widget.controller);
            }
          }
        }
        setState(() {});
      },
      child: widget.headerViewWidth != null
          ? Container(
              width: widget.headerViewWidth!(index),
              height: widget.height ?? 64.r,
              color: widget.bgColor,
              child: renderHeaderItem(index, title),
            )
          : Container(
              color: widget.bgColor,
              height: widget.height ?? 64.r,
              child: renderHeaderItem(index, title),
            ),
    ));
  }

  Widget renderHeaderItem(int index, String title) {
    bool disabled = false;
    if (widget.disabledRender != null) {
      disabled = widget.disabledRender!(index);
    }
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Expanded(
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Flexible(
                child: Text(
                  title.replaceAll('', '\u200b'),
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                  style: disabled
                      ? TextStyle(
                          fontSize: _normalStyle.fontSize,
                          color: KqThemeColors.textBF)
                      : _isShowDropDownItemWidget
                          ? widget.dropDownStyle ?? _dropDownStyle
                          : widget.style ?? _normalStyle,
                ),
              ),
              SizedBox(
                width: 16.r,
              ),
              Image.asset(
                !_isShowDropDownItemWidget
                    ? Images.commonIcArrowDown
                    : Images.commonIcArrowUpSelected,
                width: 24.r,
                height: 24.r,
                package: KqGlobal.packageName,
              ),
            ],
          ),
        ),
        index == widget.initChosenData.length - 1
            ? Container()
            : Container(
                height: widget.height ?? 64.r,
                decoration: BoxDecoration(
                  border: Border(
                    right: BorderSide(
                      color: widget.borderColor,
                      width: widget.borderWidth ?? 1.r,
                    ),
                  ),
                ),
              ),
      ],
    );
  }
}
